package com.mashibing.service;

import com.mashibing.constant.CommonStatusEnum;
import com.mashibing.constant.IdentityConstant;
import com.mashibing.constant.TokenConstantsConfiguration;
import com.mashibing.dto.ResponseResult;
import com.mashibing.remote.PassengerUserRemote;
import com.mashibing.remote.VerificationCodeRemote;
import com.mashibing.request.VerificationCodeCheck;
import com.mashibing.request.VerificationCodeRequest;
import com.mashibing.responsse.NumberCodeResponse;
import com.mashibing.util.JwtUtils;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

import static com.mashibing.util.RedisPrefixUtils.generatePhoneKey;
import static com.mashibing.util.RedisPrefixUtils.generateTokenKey;

@Service
public class VerificationCodeService {

    @Autowired
    private VerificationCodeRemote verificationCodeRemote;
//    redis
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
//    乘客登录或注册
    @Autowired
    private PassengerUserRemote passengerUser;

    /**
     * 乘客生成验证码
     * @param passengerPhone
     * @return
     */
    public ResponseResult<NumberCodeResponse> generateVerificationCode (String passengerPhone){
        /*
            1、生成代码
            2、存入redis
        * */
        // 1、生成代码
        ResponseResult<NumberCodeResponse>  verificationCode = verificationCodeRemote.getVerificationCode(5);
        int numberCode = verificationCode.getData().getNumberCode();

        /**
         * 存入redis
         *      key  前缀 + 验证码
         *      value
         */
        String key = generatePhoneKey(passengerPhone);
        stringRedisTemplate.opsForValue().set(key,numberCode+"",2, TimeUnit.MINUTES);

        JSONObject data = new JSONObject();
        data.put("numberCode",numberCode);
        ResponseResult result = ResponseResult.success("");
        return result;
    }


    /**
     * 乘客校验验证码
     */
    public ResponseResult checkVerificationCode (VerificationCodeCheck verificationCodeCheck) {
        /**
         * 1、获取乘客手机号和乘客填写的验证码
         * 2、进入redis中进行校验
         * 3、校验成功生成token，存储到服务端redis中，设置redis存储时间，当做token过期时间，此时不用单独设置token过期时间
         */

        // 1、获取乘客手机号和乘客填写的验证码
        String passengerPhone = verificationCodeCheck.getPassengerPhone();
        String verificationCode = verificationCodeCheck.getVerificationCode();

        // 2、进入redis中进行校验
        String key = generatePhoneKey(passengerPhone);
        String getVerificationCode = stringRedisTemplate.opsForValue().get(key);

        // 验证码为空
        if (StringUtils.isBlank(getVerificationCode)) {
            return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_FAIL.getCode(),CommonStatusEnum.VERIFICATION_CODE_FAIL.getMessage(),"");
        }
        // 验证码不正确
        if (!getVerificationCode.trim().equals(verificationCode.trim())) {
            return ResponseResult.fail(CommonStatusEnum.VERIFICATION_CODE_FAIL.getCode(),CommonStatusEnum.VERIFICATION_CODE_FAIL.getMessage(),"");
        }

//        判断乘客信息是否存在
        VerificationCodeRequest verificationCodeRequest = new VerificationCodeRequest();
        verificationCodeRequest.setPassengerPhone(passengerPhone);
        ResponseResult responseResult = passengerUser.loginOrRegister(verificationCodeRequest);

        /**
         * 3、校验成功生成token，存储到服务端redis中，设置redis存储时间，当做token过期时间，此时不用单独设置token过期时间
         * 生成双token  访问token 和 刷新token
         * 双token 分为 访问token：assessToken 和刷新token：refreshToken
         * 当用户访问token失效时，不立即返回认证失败，而是使用刷新token尝试再次获取双token
         * 成功则使用新的访问token，无则返回错误
         */
        // 存在 生成token
        String accessToken = JwtUtils.generatorToken(passengerPhone, IdentityConstant.PASSENGER_IDENTITY,TokenConstantsConfiguration.ACCESS_TOKEN_TYPE);
        String refreshToken = JwtUtils.generatorToken(passengerPhone, IdentityConstant.PASSENGER_IDENTITY,TokenConstantsConfiguration.REFRESH_TOKEN_TYPE);
        // token存储到服务器redis中
        String accessTokenKey = generateTokenKey(passengerPhone,IdentityConstant.PASSENGER_IDENTITY, TokenConstantsConfiguration.ACCESS_TOKEN_TYPE);
        String refreshTokenKey = generateTokenKey(passengerPhone,IdentityConstant.PASSENGER_IDENTITY, TokenConstantsConfiguration.REFRESH_TOKEN_TYPE);

        // 生产环境
        stringRedisTemplate.opsForValue().set(accessTokenKey,accessToken +"",30,TimeUnit.DAYS);
        stringRedisTemplate.opsForValue().set(refreshTokenKey,refreshToken +"",31,TimeUnit.DAYS);

        // 测试环境
//        stringRedisTemplate.opsForValue().set(accessTokenKey,accessToken +"",20,TimeUnit.SECONDS);
//        stringRedisTemplate.opsForValue().set(refreshTokenKey,refreshToken +"",60,TimeUnit.SECONDS);
        ResponseResult result = null;
        JSONObject data = new JSONObject();
        data.put("accessToken", accessToken);
        data.put("refreshToken",refreshToken);
        result = ResponseResult.success(data);
        return result;

    }
}
